package leetcode.datastructures.linkedlist;

/**
 * @author shilei
 * @create 2021-11-04 19:43
 * 双向链表演示
 */
public class DoubleLinkedListDemo {

    public static void main(String[] args) {
        HeroNode2 node1 = new HeroNode2(1, "宋江", "及时雨");
        HeroNode2 node2 = new HeroNode2(2, "卢俊义", "玉麒麟");
        HeroNode2 node3 = new HeroNode2(3, "吴用", "智多星");
        HeroNode2 node4 = new HeroNode2(4, "林冲", "豹子头");
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        //添加有顺序的
        doubleLinkedList.add(node1);
        doubleLinkedList.add(node2);
        doubleLinkedList.add(node3);
        doubleLinkedList.add(node4);
        doubleLinkedList.showList();

        System.out.println("修改后：");
        HeroNode2 node5 = new HeroNode2(4, "张三", "人人爱");
        doubleLinkedList.update(node5);
        doubleLinkedList.showList();

        System.out.println("删除后：");
        doubleLinkedList.delete(3);
        doubleLinkedList.showList();
    }
}


//创建一个双向链表
class DoubleLinkedList {
    //先初始化一个头节点 头节点不要动 不存放具体数据
    private HeroNode2 head = new HeroNode2(0, "", "");

    //返回头节点
    public HeroNode2 getHead() {
        return head;
    }

    //添加一个节点到双向链表的最后
    public void add(HeroNode2 heroNode2) {
        //因为 head节点不能动 所以我们需要一个辅助遍历 temp
        HeroNode2 temp = head;
        //遍历链表 找到最后
        while (true) {
            if (temp.next == null) {
                break;
            }
            //如果没有找到最后 将 temp 后移
            temp = temp.next;
        }
        //当退出 while 循环时 temp就指向了链表的最后
        temp.next = heroNode2;
        heroNode2.pre = temp;

    }

    //修改节点的信息 根据 no 来修改
    public void update(HeroNode2 heroNode2) {
        if (head.next == null) {
            System.out.println("链表为空~~");
            return;
        }
        //找到需要修改的节点根据no来修改
        //需要一个辅助变量指针
        HeroNode2 temp = head.next;
        boolean flag = false;//表示是否找到该节点
        while (true) {
            if (temp == null) {
                break;//已经变量完节点
            }
            if (temp.no == heroNode2.no) {
                flag = true;//找到节点 进行修改
                break;
            }
            temp = temp.next;
        }
        //根据 flag 判断是否找到要修改的节点
        if (flag) {
            temp.name = heroNode2.name;
            temp.nickName = heroNode2.nickName;
        } else {
            System.out.println("没找到对应节点");
        }
    }

    //删除当前节点对应的节点  需要临时变量做辅助指针
    //1、对于双向链表 我们可以直接找到要删除的这个节点
    //2、找到之后 自我删除就可
    public void delete(int no) {
        //判断当前链表是否为空
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        HeroNode2 temp = head.next; //辅助指针
        boolean flag = false;//标志位  标志是否找到要删除的节点
        while (true) {
            if (temp == null) { //已经到链表的最后
                break;
            }
            if (temp.no == no) {
                //说明找到
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //说明找到进行删除
//            temp.next = temp.next.next; 单向链表的删除
            temp.pre.next = temp.next;
            //这里需要判断是否为最后一个节点 如果最后一个节点再去操作会空指针
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }

        } else {
            System.out.println("未找到需要删除的节点");
        }

    }

    //显示链表[遍历]
    public void showList() {
        //判断当前链表是否为空
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = head.next;
        while (true) {
            //判断是否到链表最后
            if (temp == null) {
                break;
            }
            //输出节点信息
            System.out.println(temp);

            //将temp 后移  防止死循环 打印下一个节点
            temp = temp.next;

        }
    }

}


//定义 HeroNode 每一个 HeroNode 对象就是一个节点
class HeroNode2 {

    public int no;
    public String name;
    public String nickName;
    public HeroNode2 next; //指向下一个节点
    public HeroNode2 pre; //指向前一个节点

    public HeroNode2(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode [no = " + no + ", name = " + name + ", nickName = " + nickName + "]";
    }
}